﻿#pragma once

#include <QObject>
#include <QModbusDataUnit>
#include <QModbusDevice>
#include <QAbstractSocket>
#include "./Frameworks/EquipmentAction.h"

class QModbusTcpServer;
class AbstruactEventMediator;
class QTimer;
class QTcpSocket;



class ControlBridge : public QObject, public EquipmentAction
{
	Q_OBJECT
	
public:
	inline static QStringView const Identity = L"bridge";


	void send(QJsonObject const& msg, QStringView to) override;

public:
	ControlBridge(QObject *parent = nullptr);
	~ControlBridge();
	bool connectDevice(QString const& host, quint16 port, int device);
	QStringView identity() const override;
	void update(QJsonObject const& msg) override;
	void send(QJsonObject const& msg) override;
	void setMediator(AbstruactEventMediator* mediator) override;
	bool lock();
	bool unlock();
public slots:
	void onTcpStateChanged(QAbstractSocket::SocketState socketState);
private:
	void processUpdateRegister(QJsonObject const& obj);
	void processLock(QJsonObject const& obj);
	void processUnlock(QJsonObject const& obj);
	void processConnectState(QJsonObject const& obj);
	inline void reportLog(QString const& log,int lev = 0);
private slots:
	void updateData(QModbusDataUnit::RegisterType table, int address, int size);
	void onStateChanged(QModbusDevice::State state);
	void handleDeviceError(QModbusDevice::Error error);
	void onTimeout();
private:
	QModbusTcpServer* m_server = nullptr;
	AbstruactEventMediator* m_mediator = nullptr;
	std::map<QStringView, std::function<void(QJsonObject const&)>> m_processMsgMap;
	QTimer* m_timer = nullptr;
	int m_reConnectCount = 0;
	QList<QTcpSocket*> m_clientList;
	bool m_isControlLocked = false;
	QString m_hostStr;
	quint16 m_port;
	int m_startAddress = 0;
	int m_interval = 0;
	friend class TcpObserver;
};
